package jeu;

/**
 * Created by IntelliJ IDEA.
 * User: cvermot2
 * Date: 1 mars 2010
 * Time: 10:23:22
 * To change this template use File | Settings | File Templates.
 */
public class Awele {
    private Grille grille;
    private Joueur joueur1; // joueur id = 0
    private Joueur joueur2; // joueur id = 1
    private boolean gagner;
    private boolean finish;

    public Awele(String nomJoueur1, String nomJoueur2){
        grille = new Grille();
        joueur1 = new Joueur(nomJoueur1);
        joueur2 = new Joueur(nomJoueur2);
        gagner = false ;
        finish = false ;
    }

    public Awele(){
        this("mika", "clem");
    }

    public Grille getPlateau(){
        return grille ;
    }
    public void setPlateau(Grille grid){
        this.grille = grid ;
    }
    public boolean getGagner(){
        return gagner ;
    }
    public void setGagner(boolean gagner){
        this.gagner = gagner ;
    }
    public void setValueAtPosition(int value, int position){
        grille.setValueAtPosition(value, position);
    }
    public void setFinish(boolean finish){
        this.finish = finish;
    }
    public boolean getFinish(){
        return finish;
    }


    /*
     * Fonction retournant le score d'un joueur
     */
    public int getScore(int joueur){
        if(joueur == 0)
            return joueur1.getNbGraines();
        else
            return joueur2.getNbGraines();
    }

    /*
     * Retourne l'instance de joueur correspondant à son numéro
     */
    public Joueur getJoueur(int id){
        if(id == 0){
            return joueur1;
        }
        else{
            return joueur2;
        }
    }

    /*
     * Fonction pour deplacer les graines en fonction d'une position
     */
    public void deplacement(int position){
        int graine = grille.getValueAtPosition(position);  //On récupère le nombre de graines à cette position
        grille.setValueAtPosition(0, position);            //On lui met 0 
        int i = 1 ;
        while(graine > 0){
            if((position+i)%12 != (position)){            // On vérifie qu'il ne s'agit pas de la position de depart(sup a 12 graines)
                grille.setValueAtPosition((grille.getValueAtPosition(position+i))+1, position+i); // puis on incremente
                graine--;
            }
            i++ ;
        }           
    }


    /*
     * Fonction qui simule un ramassage, n'augmente le score d'aucun joueur
     * Utile pour verifier ensuite si un des joueurs est affamé  
     */
    public void ramasserGraineTest(int min, int pos){
        for(int i = pos ; i >= min ; i--){
            if(grille.getValueAtPosition(i) == 2 || grille.getValueAtPosition(i) == 3){  //si 2 ou 3 graines on supprime
                grille.setValueAtPosition(0, i);                
            }
            else{
                break;                                                                   // Sinon on quitte la boucle
            }
        }
    }

    
    /*
     * Fonction qui ramasse réellement les graines en fonction du joueur et de la position
     *
     */
    public void ramasserGraine(int joueur, int min, int pos){
        int graines = 0 ;

        /* ramasse que si la dernière graines tombe sur le plateau adverse */ 
        if(joueur == 0 && pos > 5){
            for(int i = pos ; i >= min ; i--){
                if(grille.getValueAtPosition(i) == 2 || grille.getValueAtPosition(i) == 3){
                    graines = grille.getValueAtPosition(i);
                    grille.setValueAtPosition(0, i);
                    joueur1.addGraines(graines);
                }
                else{
                    break;
                }
            }
        }
        if(joueur == 1 && pos <= 5){
            for(int i = pos ; i >= min ; i--){
                if(grille.getValueAtPosition(i) == 2 || grille.getValueAtPosition(i) == 3){
                    graines = grille.getValueAtPosition(i);
                    grille.setValueAtPosition(0, i);
                    joueur2.addGraines(graines);
                }
                else{
                    break;
                }
            }
        }
    }

    /*
     * Fonction moteur du jeu qui envoi des exceptions
     *
     */
    public void jouer(int joueur, int position) throws cantPlayHereException, affamerException{
        /*Test pour savoir si :
         * - Les joueurs 1 et 2 ne se sont pas trompé de plateau
         * - Le choix de la case n'a pas pour valeur de départ 0 
         */

        try{
            if(joueur == 0 && (position >=6 || position < 0)) throw new cantPlayHereException();
            if(joueur == 1 && (position <6 || position > 12)) throw new cantPlayHereException();
            if(grille.getValueAtPosition(position) == 0) throw new cantPlayHereException();
        }catch(cantPlayHereException e){
            throw new cantPlayHereException();
        }


        //Calcule de la position final et déclaration
        int pos = grille.getFinalPosition(position);
        int min  = 0;
        int max  = 0 ;
        boolean affamer  = false;
        boolean survie = false ;

        // On défini les paramètres en fonction des joueurs (min /max) 
        if(joueur == 0){
            min = 6;
            max = 11 ;
        }
        else{
            min = 0 ;
            max = 6 ;
        }
        affamer = grille.affamer(min, max); //verifie si l'adversaire est déjà affamé.
        Grille grid = new Grille();         // On créer un clone de la grille


        try{
            /* Cas 1 : l'adversaire est déjà affamé */

            if(affamer == true){
                grid.cloneGrille(this.getPlateau());    // On saugarde le plateau courant
                survie = possibilite(joueur, min, max); // On test si le joueur ne peut pas "nourrir" l'adversaire
                System.out.println("Survie = " + survie);
                if(survie == false){
                    finish = true ;
                }
                else{
                    deplacement(position);
                    affamer = grille.affamer(min, max);  // On regarde de nouveau si il est affamé
                    System.out.println("encore affamer ? " + affamer);
                    if(affamer == true) {                // Si oui, on lance une exception et on fait rejouer
                        throw new affamerException();
                    }
                }
            }

            /* Cas 2 : l'adversaire n'est pas affamé */
            else{
                grid.cloneGrille(this.getPlateau());    //Clonage
                deplacement(position);
                ramasserGraineTest(min, pos);           //On supprimes les graines qui aurait pu etre ramassées
                affamer = grille.affamer(min, max);     //On regarde si il est affamé

                /* Cas 1 : il ne l'est pas */
                if(affamer == false){
                    grille.cloneGrille(grid);           //On remet la grille d'origine
                    deplacement(position);              //On effectue le deplacement
                    ramasserGraine(joueur, min, pos);   //puis le ramassage
                }
                /* Cas 2 : il l'est */                 
                else{                    
                    grille.cloneGrille(grid);           //On remet aussi la grille d'origine
                    deplacement(position);              //et on effectue un deplacement sans ramassage (sinon encore affamé)
                }
            } 
        }catch(affamerException e){      // Si doublement affamé
            grille.cloneGrille(grid);    // Remise du plateau original 
            throw new affamerException();
        }

        /* Verifie si la partie est gagné après ce coup */
        finDePartie(joueur);
    }


    /*
     * Fonction qui vérifie si le un joueur peut jouer un qui qui n'affamera plus son adversaire   
     */
    public boolean possibilite(int joueur, int min, int max){
        boolean possible = false ;
        Grille grid = new Grille();
        grid.cloneGrille(grille);
        // Les possibilités sont testées en fonction des joueurs
        if(joueur == 0){
             for(int i = 0 ; i < 6 ; i++){
                 System.out.println("Pos " + grille.getValueAtPosition(i));
                  if(grille.getValueAtPosition(i) != 0){
                      deplacement(i);
                      if(grille.affamer(min, max) == false){
                          possible = true ;
                          System.out.println("In");
                      }
                      grille.cloneGrille(grid);

                  }
             }
        }
        else{
            for (int i = 6 ; i < 12 ; i++){
                if(grille.getValueAtPosition(i) != 0){
                    deplacement(i);
                    if(grille.affamer(min, max) == false){
                        possible = true ;
                    }
                    grille.cloneGrille(grid);
                }
            }
        }
        return possible;
    }


    /*
     * Fonction testant si la partie est fini, avec tous les cas possibles :
     *  - L'un des 2 joueurs a atteint les 25 graines
     *  - Il ne reste plus que 6 graines sur le plateau
     *  - Quelque soit le coup du joueur, l'adversaire reste affamé.
     */
    public void finDePartie(int joueur){
        if(joueur1.getNbGraines() >= 25 || joueur2.getNbGraines() >= 25){
            gagner = true ;
        }
        if(grille.getGrainesPlateau() < 6 ){
            gagner = true ;
        }
        int graines_restantes = 0 ;
        if(finish == true){
            gagner = true ;
            graines_restantes = grille.getGrainesPlateau();
            if(joueur == 0){
                joueur1.setGraines(graines_restantes);
            }
            else{
                joueur2.setGraines(graines_restantes);
            }
        }
    }
    
    
}
